﻿using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

namespace SuperGo.Silverlight {
	public partial class ComboBox {
		private object _selectedItem;
		public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.Register("IsEnabled", typeof(bool), typeof(ComboBox), null);
		readonly Canvas LayoutRoot;

		/// <summary>
		/// Constructor
		/// </summary>
		public ComboBox() {
			InitializeComponent();
			
			// set _controlBase after InitializeComponent so _stackPanel is initialized
			LayoutRoot = (Canvas)_stackPanel.Parent;

			Loaded += new RoutedEventHandler(ComboBox_Loaded);
			SizeChanged += new SizeChangedEventHandler(ComboBox_SizeChanged);
		}

		public bool IsEnabled {
			get {
				return (bool)GetValue(IsEnabledProperty);
			}
			set {
				SetValue(IsEnabledProperty, value);
			}
		}

		public Brush Foreground {
			get {
				if (IsEnabled)
					return new SolidColorBrush(Colors.Black);
				return new SolidColorBrush(Colors.Gray);
			}
		}

		public bool ReadOnly {
			get { return !IsEnabled; }
		}

		void ComboBox_SizeChanged(object sender, SizeChangedEventArgs e) {
			Resize();
		}

		public IEnumerable<object> Items { get; set; }

		public object SelectedItem {
			get { return _selectedItem; }
			set {
				ItemTextBox.Text = value.ToString();
				_selectedItem = value; 
			}
		}

		void ComboBox_Loaded(object sender, RoutedEventArgs e) {
			Dropdown.Click += new RoutedEventHandler(Dropdown_Click);
			ItemsListBox.SelectionChanged += new SelectionChangedEventHandler(ItemsListBox_SelectionChanged);
			ItemsListBox.MouseLeftButtonUp += new MouseButtonEventHandler(ItemsListBox_MouseLeftButtonUp);

			// this line was in beta1 but broke beta 2, possibly not necessary
			//ItemsListBox.DataContext = this;

			IsItemsListTextBoxVisible = false;
		}

		private void Resize() {
			FrameworkElement parentControl = LayoutRoot.Parent as FrameworkElement;
			if (parentControl != null) {
				double width = parentControl.ActualWidth;
				Resize(width);
			}
		}

		private void Resize(double width) {
			this.Width = width;
			_stackPanel.Width = width;
		}

		private bool IsItemsListTextBoxVisible {
			get {
				return ItemsListBox.Visibility == Visibility.Visible;
			}

			set {
				if (value) {
					ItemsListBox.Visibility = Visibility.Visible;
					LayoutRoot.SetValue(ZIndexProperty, 10);
				} else {
					ItemsListBox.Visibility = Visibility.Collapsed;
					LayoutRoot.SetValue(ZIndexProperty, -10);
				}
			}
		}

		void ItemsListBox_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) {
			if (WasListItemClicked(e))		
				IsItemsListTextBoxVisible = false;
		}

		/// <summary>
		/// This is really hacky, but it's the best way I can figure out how to determine
		/// if some part of the scroll bar was clicked or an actual list item was clicked.
		/// </summary>
		private static bool WasListItemClicked(RoutedEventArgs e) {
			Grid source = e.Source as Grid;
			if (source != null)
				if (source.ColumnDefinitions.Count == 0)
					return true;
			return false;
		}

		void ItemsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
			// ignore selection changed event if it list box is not visible or there is no selected item
			if (!IsItemsListTextBoxVisible || ItemsListBox.SelectedItem == null)
				return;

			SelectedItem = ItemsListBox.SelectedItem;
		}

		void Dropdown_Click(object sender, RoutedEventArgs e) {
			IsItemsListTextBoxVisible = !IsItemsListTextBoxVisible;
			ItemsListBox.ItemsSource = Items;
		}

	}
}
